/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cstdint>
#include <functional>
#include <optional>
#include <utility>

#include "gtest/gtest-message.h"
#include "gtest/gtest.h"

#define private public
#define protected public
#include "test/mock/core/common/mock_container.h"
#include "test/mock/base/mock_task_executor.h"
#include "test/mock/core/common/mock_theme_manager.h"
#include "test/mock/core/common/mock_theme_default.h"
#include "test/mock/core/pipeline/mock_pipeline_context.h"

#include "core/components/theme/icon_theme.h"
#include "core/components_ng/pattern/button/button_pattern.h"
#include "core/components_ng/pattern/time_picker/timepicker_column_pattern.h"
#include "core/components_ng/pattern/time_picker/timepicker_dialog_view.h"
#include "core/components_ng/pattern/time_picker/timepicker_row_pattern.h"
#include "core/components/common/properties/shadow_config.h"

#undef private
#undef protected

using namespace testing;
using namespace testing::ext;

namespace OHOS::Ace::NG {
namespace {
const int HALF_VALUE = 2;
const int SHOW_COUNT = 7;
const Dimension FONT_VALUE_VP = 4.0_vp;
const Dimension FONT_VALUE_NOMARL = Dimension(10);
const double CURRENT_YOFFSET1 = -200.f;
const double CURRENT_YOFFSET2 = 200.f;
const double DEFAULT_YOFFSET1 = 1.f;
const double DEFAULT_YOFFSET2 = 2.f;
const double NEXT_DISTANCE = 7.f;
const double PREVIOUS_DISTANCE = 5.f;
const uint32_t PM_INDEX = 1;
const uint32_t INDEX_HOUR_9 = 9;
const uint32_t INDEX_HOUR_10 = 10;
const uint32_t INDEX_HOUR_22 = 22;
const uint32_t INDEX_HOUR_23 = 23;
const uint32_t INDEX_MINUTE_50 = 50;
const uint32_t INDEX_SECOND_50 = 50;

RefPtr<Theme> GetTheme(ThemeType type)
{
    if (type == IconTheme::TypeId()) {
        return AceType::MakeRefPtr<IconTheme>();
    } else if (type == DialogTheme::TypeId()) {
        return AceType::MakeRefPtr<DialogTheme>();
    } else if (type == PickerTheme::TypeId()) {
        return MockThemeDefault::GetPickerTheme();
    } else if (type == ButtonTheme::TypeId()) {
        return AceType::MakeRefPtr<ButtonTheme>();
    } else {
        return nullptr;
    }
}
} // namespace
class TimePickerPatternTestUpdate : public testing::Test {
public:
    static void SetUpTestSuite();
    static void TearDownTestSuite();
    void SetUp() override;
    void TearDown() override;
    void CreateTimePickerColumnNode();
    bool CompareOptionProperties(std::vector<PickerOptionProperty> option1, std::vector<PickerOptionProperty> option2)
    {
        int32_t size = option1.size();
        for (int32_t i = 0; i < size; i++) {
            if (option1[i].height != option2[i].height ||
                option1[i].fontheight != option2[i].fontheight ||
                option1[i].prevDistance != option2[i].prevDistance ||
                option1[i].nextDistance != option2[i].nextDistance) {
                return false;
            }
        }
        return true;
    }

    RefPtr<FrameNode> columnNode_;
    RefPtr<TimePickerColumnPattern> columnPattern_;
};

class TestNode : public UINode {
    DECLARE_ACE_TYPE(TestNode, UINode);

public:
    static RefPtr<TestNode> CreateTestNode(int32_t nodeId)
    {
        auto spanNode = MakeRefPtr<TestNode>(nodeId);
        return spanNode;
    }

    bool IsAtomicNode() const override
    {
        return true;
    }

    explicit TestNode(int32_t nodeId) : UINode("TestNode", nodeId) {}
    ~TestNode() override = default;
};

void TimePickerPatternTestUpdate::SetUpTestSuite()
{
    MockPipelineContext::SetUp();
    MockContainer::SetUp();
}

void TimePickerPatternTestUpdate::TearDownTestSuite()
{
    MockPipelineContext::TearDown();
    MockContainer::TearDown();
}

void TimePickerPatternTestUpdate::SetUp()
{
    auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
    EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly([](ThemeType type) -> RefPtr<Theme> {
        return GetTheme(type);
    });
    EXPECT_CALL(*themeManager, GetTheme(_, _))
        .WillRepeatedly([](ThemeType type, int32_t themeScopeId) -> RefPtr<Theme> { return GetTheme(type); });
    MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
}

void TimePickerPatternTestUpdate::TearDown()
{
    MockPipelineContext::GetCurrent()->themeManager_ = nullptr;
    ViewStackProcessor::GetInstance()->ClearStack();
}

void TimePickerPatternTestUpdate::CreateTimePickerColumnNode()
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);
    auto pickerFrameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(pickerFrameNode, nullptr);
    pickerFrameNode->MarkModifyDone();

    auto timePickerRowPattern = pickerFrameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    timePickerRowPattern->UpdateAllChildNode();
    auto allChildNode = timePickerRowPattern->GetAllChildNode();
    columnNode_ = allChildNode["minute"].Upgrade();
    ASSERT_NE(columnNode_, nullptr);
    columnPattern_ = columnNode_->GetPattern<TimePickerColumnPattern>();
    ASSERT_NE(columnPattern_, nullptr);
    columnPattern_->SetShowCount(SHOW_COUNT);
    columnPattern_->OnAttachToFrameNode();
    auto host = timePickerRowPattern->GetHost();
    EXPECT_NE(host, nullptr);
}

/**
 * @tc.name: TimePickerModelNGTest001
 * @tc.desc: Test TimePickerModelNG CreateFrameNode.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest001, TestSize.Level1)
{
    /**
     * @tc.step: step1. create timePickerModelNG.
     */
    CreateTimePickerColumnNode();
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    TimePickerModelNG timePickerModelNG;
    /**
     * @tc.step: step1. create TimepickerNode.
     * @tc.expected: timePickerNode is not NULL.
     */
    auto timePickerNode = timePickerModelNG.CreateFrameNode(frameNode->GetId());
    EXPECT_NE(timePickerNode, nullptr);
}

/**
 * @tc.name: TimePickerModelNGTest002
 * @tc.desc: Test TimePickerModelNG SetTimePickerDialogShow.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest002, TestSize.Level1)
{
    /**
     * @tc.step: step1. create timePickerModelNG.
     */
    CreateTimePickerColumnNode();
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    auto pipeline = PipelineBase::GetCurrentContextSafely();
    auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
    MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    TimePickerDialogModelNG timePickerDialogModelNG;

    PickerDialogInfo pickerDialog;
    NG::TimePickerSettingData settingData;
    std::function<void()> onCancel = []() {};
    std::function<void(const std::string&)> onAccept = [](const std::string&) {};
    std::function<void(const std::string&)> onChange = [](const std::string&) {};
    std::function<void(const std::string&)> onEnterSelectedArea = [](const std::string&) {};
    TimePickerDialogEvent timePickerDialogEvent;
    std::vector<ButtonInfo> buttonInfos;

    timePickerDialogModelNG.SetTimePickerDialogShow(pickerDialog, settingData, std::move(onCancel),
        std::move(onAccept), std::move(onChange), std::move(onEnterSelectedArea), timePickerDialogEvent, buttonInfos);
    ASSERT_NE(frameNode, nullptr);
}

/**
 * @tc.name: CreateFrameNode001
 * @tc.desc: Test TimePickerPatternTestUpdate CreateFrameNode.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, CreateFrameNode001, TestSize.Level1)
{
    int32_t nodeId = 0;
    RefPtr<FrameNode> result = TimePickerModelNG::CreateFrameNode(nodeId);
    EXPECT_NE(result, nullptr);
    auto timePickerRowPattern = result->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    timePickerRowPattern->hourId_ = 1;
    timePickerRowPattern->minuteId_ = 1;
    TimePickerModelNG::CreateFrameNode(nodeId);
}

/**
 * @tc.name: SetDisappearTextStyle001
 * @tc.desc: Test TimePickerPatternTestUpdate SetDisappearTextStyle.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, SetDisappearTextStyle001, TestSize.Level1)
{
    std::string weight = "FontWeight.Medium";
    std::string fontFamily = "";
    std::string FORMAT_FONT = "%s|%s|%s";
    std::string fontSize = "20";
    std::string fontInfo =
        StringUtils::FormatString(FORMAT_FONT.c_str(), fontSize.c_str(), weight.c_str(), fontFamily.c_str());
    uint32_t color = 0;
    int32_t POS_0 = 0;
    const char delimiter = '|';
    int32_t style = 0;
    const std::vector<OHOS::Ace::FontStyle> FONT_STYLES = { OHOS::Ace::FontStyle::NORMAL,
        OHOS::Ace::FontStyle::ITALIC };
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    NG::PickerTextStyle textStyle;
    std::vector<std::string> res;
    std::string fontValues = std::string(fontInfo.c_str());
    StringUtils::StringSplitter(fontValues, delimiter, res);
    textStyle.fontSize = StringUtils::StringToCalcDimension(res[POS_0], false, DimensionUnit::FP);
    if (style >= 0 && style < static_cast<int32_t>(FONT_STYLES.size())) {
        textStyle.fontStyle = FONT_STYLES[style];
    } else {
        textStyle.fontStyle = FONT_STYLES[0];
    }
    textStyle.textColor = Color(color);
    TimePickerModelNG::SetDisappearTextStyle(frameNode, theme, textStyle);
}

/**
 * @tc.name: GetDisappearTextStyle001
 * @tc.desc: Test TimePickerPatternTestUpdate GetDisappearTextStyle by frameNode.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, GetDisappearTextStyle001, TestSize.Level1)
{
    /**
     * @tc.step: step1. create timePickerModelNG.
     */
    CreateTimePickerColumnNode();
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    NG::PickerTextStyle textStyle;
    textStyle.fontStyle = Ace::FontStyle::ITALIC;
    textStyle.textColor = Color::WHITE;
    TimePickerModelNG::SetDisappearTextStyle(frameNode, theme, textStyle);
    auto curTextStyle = TimePickerModelNG::getDisappearTextStyle(frameNode);
    EXPECT_EQ(curTextStyle.fontStyle.value(), Ace::FontStyle::ITALIC);
    EXPECT_EQ(curTextStyle.textColor.value(), Color::WHITE);
}

/**
 * @tc.name: SetNormalTextStyle001
 * @tc.desc: Test TimePickerPatternTestUpdate SetNormalTextStyle.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, SetNormalTextStyle001, TestSize.Level1)
{
    std::string weight = "FontWeight.Medium";
    std::string fontFamily = "";
    std::string FORMAT_FONT = "%s|%s|%s";
    std::string fontSize = "20";
    std::string fontInfo =
        StringUtils::FormatString(FORMAT_FONT.c_str(), fontSize.c_str(), weight.c_str(), fontFamily.c_str());
    uint32_t color = 0;
    int32_t POS_0 = 0;
    const char delimiter = '|';
    int32_t style = 0;
    const std::vector<OHOS::Ace::FontStyle> FONT_STYLES = { OHOS::Ace::FontStyle::NORMAL,
        OHOS::Ace::FontStyle::ITALIC };
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    NG::PickerTextStyle textStyle;
    std::vector<std::string> res;
    std::string fontValues = std::string(fontInfo);
    StringUtils::StringSplitter(fontValues, delimiter, res);
    textStyle.fontSize = StringUtils::StringToCalcDimension(res[POS_0], false, DimensionUnit::FP);
    if (style >= 0 && style < static_cast<int32_t>(FONT_STYLES.size())) {
        textStyle.fontStyle = FONT_STYLES[style];
    } else {
        textStyle.fontStyle = FONT_STYLES[0];
    }
    textStyle.textColor = Color(color);
    TimePickerModelNG::SetNormalTextStyle(frameNode, theme, textStyle);
}

/**
 * @tc.name: SetNormalTextStyle002
 * @tc.desc: Test TimePickerPatternTestUpdate SetNormalTextStyle.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, SetNormalTextStyle002, TestSize.Level1)
{
    std::string weight = "FontWeight.Medium";
    std::string fontFamily = "";
    std::string FORMAT_FONT = "%s|%s|%s";
    std::string fontSize = "";
    std::string fontInfo =
        StringUtils::FormatString(FORMAT_FONT.c_str(), fontSize.c_str(), weight.c_str(), fontFamily.c_str());
    uint32_t color = 0;
    int32_t POS_0 = 0;
    const char delimiter = '|';
    int32_t style = 0;
    const std::vector<OHOS::Ace::FontStyle> FONT_STYLES = { OHOS::Ace::FontStyle::NORMAL,
        OHOS::Ace::FontStyle::ITALIC };
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    NG::PickerTextStyle textStyle;
    std::vector<std::string> res;
    std::string fontValues = std::string(fontInfo);
    StringUtils::StringSplitter(fontValues, delimiter, res);
    textStyle.fontSize = StringUtils::StringToCalcDimension(res[POS_0], false, DimensionUnit::FP);
    if (style >= 0 && style < static_cast<int32_t>(FONT_STYLES.size())) {
        textStyle.fontStyle = FONT_STYLES[style];
    } else {
        textStyle.fontStyle = FONT_STYLES[0];
    }
    textStyle.textColor = Color(color);
    TimePickerModelNG::SetNormalTextStyle(frameNode, theme, textStyle);
}

/**
 * @tc.name: SetSelectedTextStyle001
 * @tc.desc: Test TimePickerPatternTestUpdate SetSelectedTextStyle.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, SetSelectedTextStyle001, TestSize.Level1)
{
    std::string weight = "FontWeight.Medium";
    std::string fontFamily = "";
    std::string FORMAT_FONT = "%s|%s|%s";
    std::string fontSize = "20";
    std::string fontInfo =
        StringUtils::FormatString(FORMAT_FONT.c_str(), fontSize.c_str(), weight.c_str(), fontFamily.c_str());
    uint32_t color = 0;
    int32_t POS_0 = 0;
    const char delimiter = '|';
    int32_t style = 0;
    const std::vector<OHOS::Ace::FontStyle> FONT_STYLES = { OHOS::Ace::FontStyle::NORMAL,
        OHOS::Ace::FontStyle::ITALIC };
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    NG::PickerTextStyle textStyle;
    std::vector<std::string> res;
    std::string fontValues = std::string(fontInfo);
    StringUtils::StringSplitter(fontValues, delimiter, res);
    textStyle.fontSize = StringUtils::StringToCalcDimension(res[POS_0], false, DimensionUnit::FP);
    if (style >= 0 && style < static_cast<int32_t>(FONT_STYLES.size())) {
        textStyle.fontStyle = FONT_STYLES[style];
    } else {
        textStyle.fontStyle = FONT_STYLES[0];
    }
    textStyle.textColor = Color(color);
    TimePickerModelNG::SetSelectedTextStyle(frameNode, theme, textStyle);
}

/**
 * @tc.name: SetSelectedTextStyle002
 * @tc.desc: Test TimePickerPatternTestUpdate SetSelectedTextStyle.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, SetSelectedTextStyle002, TestSize.Level1)
{
    std::string weight = "FontWeight.Medium";
    std::string fontFamily = "";
    std::string FORMAT_FONT = "%s|%s|%s";
    std::string fontSize = "";
    std::string fontInfo =
        StringUtils::FormatString(FORMAT_FONT.c_str(), fontSize.c_str(), weight.c_str(), fontFamily.c_str());
    uint32_t color = 0;
    int32_t POS_0 = 0;
    const char delimiter = '|';
    int32_t style = 0;
    const std::vector<OHOS::Ace::FontStyle> FONT_STYLES = { OHOS::Ace::FontStyle::NORMAL,
        OHOS::Ace::FontStyle::ITALIC };
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    NG::PickerTextStyle textStyle;
    std::vector<std::string> res;
    std::string fontValues = std::string(fontInfo);
    StringUtils::StringSplitter(fontValues, delimiter, res);
    textStyle.fontSize = StringUtils::StringToCalcDimension(res[POS_0], false, DimensionUnit::FP);
    if (style >= 0 && style < static_cast<int32_t>(FONT_STYLES.size())) {
        textStyle.fontStyle = FONT_STYLES[style];
    } else {
        textStyle.fontStyle = FONT_STYLES[0];
    }
    textStyle.textColor = Color(color);
    TimePickerModelNG::SetSelectedTextStyle(frameNode, theme, textStyle);
}

/**
 * @tc.name: SetDateTimeOptions001
 * @tc.desc: Test TimePickerPatternTestUpdate SetDateTimeOptions.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, SetDateTimeOptions001, TestSize.Level1)
{
    TimePickerModelNG timepickerModel;
    auto* stack = ViewStackProcessor::GetInstance();
    ASSERT_NE(stack, nullptr);
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    ZeroPrefixType hideType = ZeroPrefixType::HIDE;
    ZeroPrefixType showType = ZeroPrefixType::SHOW;
    ZeroPrefixType offType = ZeroPrefixType::OFF;
    auto timePickerRowPattern = frameNode->GetPattern<TimePickerRowPattern>();
    timepickerModel.SetDateTimeOptions(frameNode, hideType, showType, hideType);
    EXPECT_FALSE(timePickerRowPattern->isDateTimeOptionUpdate_);
    ASSERT_NE(timePickerRowPattern, nullptr);
    timePickerRowPattern->SetPrefixHour(showType);
    timePickerRowPattern->SetPrefixMinute(showType);
    timePickerRowPattern->SetPrefixSecond(showType);
    timepickerModel.SetDateTimeOptions(hideType, hideType, hideType);
    EXPECT_TRUE(timePickerRowPattern->isDateTimeOptionUpdate_);
    timepickerModel.SetDateTimeOptions(hideType, hideType, offType);
    EXPECT_TRUE(timePickerRowPattern->isDateTimeOptionUpdate_);
}

/**
 * @tc.name: GetSecondColumnFormatString001
 * @tc.desc: Test TimePickerPatternTestUpdate GetSecondColumnFormatString.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, GetSecondColumnFormatString001, TestSize.Level1)
{
    uint32_t second = 0;
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);
    auto pickerFrameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(pickerFrameNode, nullptr);
    pickerFrameNode->MarkModifyDone();

    auto timePickerRowPattern = pickerFrameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    auto secondString = timePickerRowPattern->GetSecondColumnFormatString(second);
    EXPECT_EQ(secondString, "00");
}

/**
 * @tc.name: OnAroundButtonClick001
 * @tc.desc: Test TimePickerPatternTestUpdate OnAroundButtonClick.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, OnAroundButtonClick001, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);
    auto pickerFrameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(pickerFrameNode, nullptr);
    pickerFrameNode->MarkModifyDone();
    auto timePickerRowPattern = pickerFrameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    timePickerRowPattern->UpdateAllChildNode();
    auto allChildNode = timePickerRowPattern->GetAllChildNode();
    columnNode_ = allChildNode["minute"].Upgrade();
    ASSERT_NE(columnNode_, nullptr);
    columnPattern_ = columnNode_->GetPattern<TimePickerColumnPattern>();
    ASSERT_NE(columnPattern_, nullptr);
    auto host = timePickerRowPattern->GetHost();
    EXPECT_NE(host, nullptr);

    auto childSize = static_cast<int32_t>(host->GetChildren().size());
    for (int32_t i = 0; i < childSize; i++) {
        RefPtr<FrameNode> childNode = AceType::DynamicCast<FrameNode>(host->GetChildAtIndex(i));
        CHECK_NULL_VOID(childNode);

        RefPtr<PickerEventParam> param = AceType::MakeRefPtr<PickerEventParam>();
        param->instance_ = childNode;
        param->itemIndex_ = i;
        param->itemTotalCounts_ = childSize;
        columnPattern_->OnAroundButtonClick(param);
    }
}

/**
 * @tc.name: OnWindowHide001
 * @tc.desc: Test TimePickerPatternTestUpdate OnWindowHide.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, OnWindowHide001, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);
    auto pickerFrameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(pickerFrameNode, nullptr);
    pickerFrameNode->MarkModifyDone();
    auto timePickerRowPattern = pickerFrameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    timePickerRowPattern->UpdateAllChildNode();
    auto allChildNode = timePickerRowPattern->GetAllChildNode();
    columnNode_ = allChildNode["minute"].Upgrade();
    ASSERT_NE(columnNode_, nullptr);
    columnPattern_ = columnNode_->GetPattern<TimePickerColumnPattern>();
    ASSERT_NE(columnPattern_, nullptr);

    columnPattern_->OnWindowHide();
}

/**
 * @tc.name: SetIsEnableHapticFeedback001
 * @tc.desc: Test TimePickerPatternTestUpdate SetIsEnableHapticFeedback.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, SetIsEnableHapticFeedback001, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);

    bool isEnableHapticFeedback = true;
    TimePickerModelNG::GetInstance()->SetIsEnableHapticFeedback(isEnableHapticFeedback);

    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    EXPECT_EQ(TimePickerModelNG::getEnableHapticFeedback(frameNode), isEnableHapticFeedback);
}

/**
 * @tc.name: SetIsEnableHapticFeedback002
 * @tc.desc: Test TimePickerPatternTestUpdate SetIsEnableHapticFeedback.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, SetIsEnableHapticFeedback002, TestSize.Level1)
{
    bool isEnableHapticFeedback = true;
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    TimePickerModelNG::SetIsEnableHapticFeedback(frameNode, isEnableHapticFeedback);
    EXPECT_EQ(TimePickerModelNG::getEnableHapticFeedback(frameNode), isEnableHapticFeedback);
}

/**
 * @tc.name: GetCurrentTime001
 * @tc.desc: Test TimePickerPatternTestUpdate GetCurrentTime.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, GetCurrentTime001, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);
    auto pickerFrameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(pickerFrameNode, nullptr);
    pickerFrameNode->MarkModifyDone();
    PickerTime selectedTime { 22, 50, 50 };
    TimePickerModelNG::GetInstance()->SetSelectedTime(selectedTime);
    TimePickerModelNG::GetInstance()->SetHour24(true);
    auto timePickerRowPattern = pickerFrameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    timePickerRowPattern->SetHasSecond(true);

    /**
     * @tc.steps: step2. check hour_, minute_ and second_ of current time are set as selected time.
     * @tc.expected: hour_ is 22, minute_ is 50, and second_ is 50.
     */
    timePickerRowPattern->GetCurrentTime();
    auto hasSecond = timePickerRowPattern->GetHasSecond();
    EXPECT_EQ(hasSecond, true);
}

/**
 * @tc.name: TimePickerModelNGTest003
 * @tc.desc: Test TimePickerModelNG SetTimePickerDialogShow.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest003, TestSize.Level1)
{
    /**
     * @tc.step: step1. create timePickerModelNG.
     */
    MockContainer::Current()->taskExecutor_ = AceType::MakeRefPtr<MockTaskExecutor>();
    MockContainer::Current()->pipelineContext_ = MockPipelineContext::GetCurrentContext();
    MockContainer::Current()->pipelineContext_->taskExecutor_ = MockContainer::Current()->taskExecutor_;
    int32_t rollbackApiVersion = MockContainer::Current()->GetApiTargetVersion();
    MockContainer::Current()->SetApiTargetVersion(10);
    CreateTimePickerColumnNode();
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    TimePickerDialogModelNG timePickerDialogModelNG;

    PickerDialogInfo pickerDialog;
    NG::TimePickerSettingData settingData;
    std::function<void()> onCancel = []() {};
    std::function<void(const std::string&)> onAccept = [](const std::string&) {};
    std::function<void(const std::string&)> onChange = [](const std::string&) {};
    std::function<void(const std::string&)> onEnterSelectedArea = [](const std::string&) {};
    TimePickerDialogEvent timePickerDialogEvent;
    std::vector<ButtonInfo> buttonInfos;

    timePickerDialogModelNG.SetTimePickerDialogShow(pickerDialog, settingData, std::move(onCancel), std::move(onAccept),
        std::move(onChange), std::move(onEnterSelectedArea), timePickerDialogEvent, buttonInfos);
    MockContainer::Current()->SetApiTargetVersion(rollbackApiVersion);
    ASSERT_NE(frameNode, nullptr);
    pickerDialog.alignment = DialogAlignment::CENTER;
    pickerDialog.backgroundColor = Color(100);
    pickerDialog.backgroundBlurStyle = 1;
    pickerDialog.shadow = ShadowConfig::DefaultShadowL;
    pickerDialog.offset = DimensionOffset(Offset(0, 1.0f));
    pickerDialog.isSelectedTime = true;
    timePickerDialogModelNG.SetTimePickerDialogShow(pickerDialog, settingData, std::move(onCancel), std::move(onAccept),
        std::move(onChange), std::move(onEnterSelectedArea), timePickerDialogEvent, buttonInfos);
    ASSERT_NE(frameNode, nullptr);
}

/**
 * @tc.name: TimePickerModelNGTest004
 * @tc.desc: Test TimePickerModelNG CreateTimePicker.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest004, TestSize.Level1)
{
    auto pipeline = MockPipelineContext::GetCurrentContext();
    ASSERT_NE(pipeline, nullptr);
    pipeline->SetFontScale(0);
    TimePickerModelNG timepickerModel;
    auto ret = timepickerModel.ConvertFontScaleValue(FONT_VALUE_NOMARL);
    EXPECT_EQ(ret, FONT_VALUE_NOMARL);

    pipeline->SetFontScale(10);
    ret = timepickerModel.ConvertFontScaleValue(FONT_VALUE_VP);
    EXPECT_EQ(ret, FONT_VALUE_VP);

    ret = timepickerModel.ConvertFontScaleValue(FONT_VALUE_NOMARL);
    EXPECT_EQ(ret, FONT_VALUE_NOMARL);
}

/**
 * @tc.name: TimePickerModelNGTest005
 * @tc.desc: Test TimePickerModelNG SetEnableCascade.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest005, TestSize.Level1)
{
    int32_t nodeId = 0;
    RefPtr<FrameNode> result = TimePickerModelNG::CreateFrameNode(nodeId);
    EXPECT_NE(result, nullptr);
    bool isEnableCascade = false;
    auto timePickerRowPattern = result->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    timePickerRowPattern->SetEnableCascade(isEnableCascade);
    bool ret = timePickerRowPattern->GetEnableCascade();
    EXPECT_EQ(ret, false);

    isEnableCascade = true;
    timePickerRowPattern->SetEnableCascade(isEnableCascade);
    ret = timePickerRowPattern->GetEnableCascade();
    EXPECT_EQ(ret, true);
}

/**
 * @tc.name: TimePickerModelNGTest006
 * @tc.desc: Test TimePickerModelNG SetStartTime and GetStartTime.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest006, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);
    PickerTime value { 0, 0, 0 };
    TimePickerModelNG::GetInstance()->SetStartTime(value);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    auto timePickerRowPattern = frameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    auto time = timePickerRowPattern->GetStartTime();
    EXPECT_EQ(time.hour_, 0);
    EXPECT_EQ(time.minute_, 0);
    EXPECT_EQ(time.second_, 0);

    PickerTime valuBoundary { 23, 59, 59 };
    TimePickerModelNG::GetInstance()->SetStartTime(valuBoundary);
    auto timeBoundary = timePickerRowPattern->GetStartTime();
    EXPECT_EQ(timeBoundary.hour_, 23);
    EXPECT_EQ(timeBoundary.minute_, 59);
    EXPECT_EQ(timeBoundary.second_, 59);

    PickerTime valuIllegal { 24, 61, 61 };
    TimePickerModelNG::GetInstance()->SetStartTime(valuIllegal);
    auto timeIllegal = timePickerRowPattern->GetStartTime();
    EXPECT_EQ(timeIllegal.hour_, 24);
    EXPECT_EQ(timeIllegal.minute_, 61);
    EXPECT_EQ(timeIllegal.second_, 61);
}
/**
 * @tc.name: TimePickerModelNGTest007
 * @tc.desc: Test TimePickerModelNG SetEndTime and GetEndTime.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest007, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);
    PickerTime value { 0, 0, 0 };
    TimePickerModelNG::GetInstance()->SetEndTime(value);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    auto timePickerRowPattern = frameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    auto time = timePickerRowPattern->GetEndTime();
    EXPECT_EQ(time.hour_, 0);
    EXPECT_EQ(time.minute_, 0);
    EXPECT_EQ(time.second_, 0);

    PickerTime valuBoundary { 23, 59, 59 };
    TimePickerModelNG::GetInstance()->SetEndTime(valuBoundary);
    auto timeBoundary = timePickerRowPattern->GetEndTime();
    EXPECT_EQ(timeBoundary.hour_, 23);
    EXPECT_EQ(timeBoundary.minute_, 59);
    EXPECT_EQ(timeBoundary.second_, 59);

    PickerTime valuIllegal { 24, 61, 61 };
    TimePickerModelNG::GetInstance()->SetEndTime(valuIllegal);
    auto timeIllegal = timePickerRowPattern->GetEndTime();
    EXPECT_EQ(timeIllegal.hour_, 24);
    EXPECT_EQ(timeIllegal.minute_, 61);
    EXPECT_EQ(timeIllegal.second_, 61);
}
/**
 * @tc.name: TimePickerModelNGTest008
 * @tc.desc: Test TimePickerModelNG SetStartTime and getTimepickerStart.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest008, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);
    PickerTime value { 0, 0, 0 };
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    TimePickerModelNG::SetStartTime(frameNode, value);
    auto time = TimePickerModelNG::getTimepickerStart(frameNode);

    EXPECT_EQ(time.hour_, 0);
    EXPECT_EQ(time.minute_, 0);
    EXPECT_EQ(time.second_, 0);

    PickerTime valuBoundary { 23, 59, 59 };
    TimePickerModelNG::SetStartTime(frameNode, valuBoundary);
    auto timeBoundary = TimePickerModelNG::getTimepickerStart(frameNode);
    EXPECT_EQ(timeBoundary.hour_, 23);
    EXPECT_EQ(timeBoundary.minute_, 59);
    EXPECT_EQ(timeBoundary.second_, 59);

    PickerTime valuIllegal { 24, 61, 61 };
    TimePickerModelNG::SetStartTime(frameNode, valuBoundary);
    auto timeIllegal = TimePickerModelNG::getTimepickerStart(frameNode);
    EXPECT_EQ(timeIllegal.hour_, 23);
    EXPECT_EQ(timeIllegal.minute_, 59);
    EXPECT_EQ(timeIllegal.second_, 59);
}
/**
 * @tc.name: TimePickerModelNGTest009
 * @tc.desc: Test TimePickerModelNG SetEndTime and getTimepickerEnd.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest009, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);
    PickerTime value { 0, 0, 0 };
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    TimePickerModelNG::SetEndTime(frameNode, value);
    auto time = TimePickerModelNG::getTimepickerEnd(frameNode);

    EXPECT_EQ(time.hour_, 0);
    EXPECT_EQ(time.minute_, 0);
    EXPECT_EQ(time.second_, 0);

    PickerTime valuBoundary { 23, 59, 59 };
    TimePickerModelNG::SetEndTime(frameNode, valuBoundary);
    auto timeBoundary = TimePickerModelNG::getTimepickerEnd(frameNode);
    EXPECT_EQ(timeBoundary.hour_, 23);
    EXPECT_EQ(timeBoundary.minute_, 59);
    EXPECT_EQ(timeBoundary.second_, 59);

    PickerTime valuIllegal { 24, 61, 61 };
    TimePickerModelNG::SetEndTime(frameNode, valuBoundary);
    auto timeIllegal = TimePickerModelNG::getTimepickerEnd(frameNode);
    EXPECT_EQ(timeIllegal.hour_, 23);
    EXPECT_EQ(timeIllegal.minute_, 59);
    EXPECT_EQ(timeIllegal.second_, 59);
}
/**
 * @tc.name: TimePickerModelNGTest010
 * @tc.desc: Test TimePickerModelNG ParseHourOf24.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest010, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);

    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    auto timePickerRowPattern = frameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    PickerTime value10 { 10, 40, 42 };
    auto hour = timePickerRowPattern->ParseHourOf24(value10.GetHour());
    EXPECT_EQ(hour, 10);
    PickerTime value23 { 23, 40, 42 };
    hour = timePickerRowPattern->ParseHourOf24(value23.GetHour());
    EXPECT_EQ(hour, 11);
}

/**
 * @tc.name: TimePickerModelNGTest011
 * @tc.desc: Test TimePickerModelNG SetEndTime, SetHour24 and format has second.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest011, TestSize.Level1)
{
    /**
     * @tc.step: step1. create timePickerModelNG, set end time and selected time.
     */
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme, true);
    PickerTime valuBoundary { 23, 50, 50 };
    TimePickerModelNG::GetInstance()->SetEndTime(valuBoundary);
    PickerTime selectedTime { 22, 50, 50 };
    TimePickerModelNG::GetInstance()->SetSelectedTime(selectedTime);
    TimePickerModelNG::GetInstance()->SetHour24(true);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    auto timePickerRowPattern = frameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    /**
     * @tc.steps: step2. check hour_, minute_ and second_ of end time.
     * @tc.expected: hour_ is 23, minute_ is 50, and second_ is 50.
     */
    auto timeBoundary = timePickerRowPattern->GetEndTime();
    EXPECT_EQ(timeBoundary.hour_, INDEX_HOUR_23);
    EXPECT_EQ(timeBoundary.minute_, INDEX_MINUTE_50);
    EXPECT_EQ(timeBoundary.second_, INDEX_SECOND_50);
    timePickerRowPattern->OnModifyDone();
    EXPECT_EQ(timePickerRowPattern->GetHour24(), true);

    /**
     * @tc.steps: step3. check hour_, minute_ and second_ of current time are set as selected time.
     * @tc.expected: hour_ is 22, minute_ is 50, and second_ is 50.
     */
    std::unordered_map<uint32_t, std::string> minuteMap;
    minuteMap[50] = "50";
    auto children = timePickerRowPattern->GetAllChildNode();
    timePickerRowPattern->options_[children["minute"]] = minuteMap;
    auto currentTime = timePickerRowPattern->GetCurrentTime();
    EXPECT_EQ(currentTime.hour_, INDEX_HOUR_22);
    EXPECT_EQ(currentTime.minute_, INDEX_MINUTE_50);
    EXPECT_EQ(currentTime.second_, INDEX_SECOND_50);
    auto hasSecond = timePickerRowPattern->GetHasSecond();
    EXPECT_EQ(hasSecond, true);
}

/**
 * @tc.name: TimePickerModelNGTest012
 * @tc.desc: Test TimePickerModelNG, SetEndTime and handle column change.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest012, TestSize.Level1)
{
    /**
     * @tc.step: step1. create timePickerModelNG, set end time and selected time.
     */
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme, true);
    PickerTime valuBoundary { 23, 50, 50 };
    TimePickerModelNG::GetInstance()->SetEndTime(valuBoundary);
    PickerTime selectedTime { 22, 50, 50 };
    TimePickerModelNG::GetInstance()->SetSelectedTime(selectedTime);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    frameNode->MarkModifyDone();
    auto timePickerRowPattern = frameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);

    /**
     * @tc.steps: step2. check ampm column, hour column, minute column and second column are set as the seleted time.
     * @tc.expected: ampm column's index is 1, hour column's index is 10, minute column's index is 50, and second
     * column's index is 50.
     */
    auto allChildNode = timePickerRowPattern->GetAllChildNode();
    auto amPmColumn = allChildNode["amPm"].Upgrade();
    ASSERT_NE(amPmColumn, nullptr);
    auto amPmColumnPattern = amPmColumn->GetPattern<TimePickerColumnPattern>();
    ASSERT_NE(amPmColumnPattern, nullptr);
    EXPECT_EQ(amPmColumnPattern->GetCurrentIndex(), PM_INDEX); // PM

    auto hourColumn = allChildNode["hour"].Upgrade();
    ASSERT_NE(hourColumn, nullptr);
    auto hourColumnPattern = hourColumn->GetPattern<TimePickerColumnPattern>();
    ASSERT_NE(hourColumnPattern, nullptr);
    EXPECT_EQ(hourColumnPattern->GetCurrentIndex(), INDEX_HOUR_10); // 22 => 10 PM

    auto minuteColumn = allChildNode["minute"].Upgrade();
    ASSERT_NE(minuteColumn, nullptr);
    auto minuteColumnPattern = minuteColumn->GetPattern<TimePickerColumnPattern>();
    ASSERT_NE(minuteColumnPattern, nullptr);
    EXPECT_EQ(minuteColumnPattern->GetCurrentIndex(), INDEX_MINUTE_50);

    auto secondColumn = allChildNode["second"].Upgrade();
    ASSERT_NE(secondColumn, nullptr);
    auto secondColumnPattern = secondColumn->GetPattern<TimePickerColumnPattern>();
    ASSERT_NE(secondColumnPattern, nullptr);
    EXPECT_EQ(secondColumnPattern->GetCurrentIndex(), INDEX_SECOND_50);

    /**
     * @tc.steps: step3. set hour column to 9 then check ampm column, hour column, minute column and second column are
     * set as the seleted time except the changed hour column.
     * @tc.expected: ampm column's index is PM_INDEX, hour column's index is 9, minute column's index is 50, and second
     * column's index is 50.
     */
    hourColumnPattern->SetCurrentIndex(INDEX_HOUR_9);
    timePickerRowPattern->HandleColumnsChangeTimeRange(hourColumn, true);
    EXPECT_EQ(amPmColumnPattern->GetCurrentIndex(), PM_INDEX);
    EXPECT_EQ(hourColumnPattern->GetCurrentIndex(), INDEX_HOUR_9);
    EXPECT_EQ(minuteColumnPattern->GetCurrentIndex(), INDEX_MINUTE_50);
    EXPECT_EQ(secondColumnPattern->GetCurrentIndex(), INDEX_SECOND_50);
}

/**
 * @tc.name: TimePickerModelNGTest013
 * @tc.desc: Test TimePickerModelNG SetOnChange.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest013, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme, true);
    auto timePickerModelNG = TimePickerModelNG::GetInstance();
    CHECK_NULL_VOID(timePickerModelNG);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    CHECK_NULL_VOID(frameNode);
    auto eventHub = frameNode->GetEventHub<TimePickerEventHub>();
    CHECK_NULL_VOID(eventHub);
    auto changeEvent = [](const BaseEventInfo* info) {};
    timePickerModelNG->SetOnChange(changeEvent);
    EXPECT_NE(eventHub->changeEvent_, nullptr);
}

/**
 * @tc.name: TimePickerModelNGTest014
 * @tc.desc: Test TimePickerModelNG SetOnChange.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest014, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme, true);
    auto timePickerModelNG = TimePickerModelNG::GetInstance();
    CHECK_NULL_VOID(timePickerModelNG);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    CHECK_NULL_VOID(frameNode);
    auto eventHub = frameNode->GetEventHub<TimePickerEventHub>();
    CHECK_NULL_VOID(eventHub);
    auto changeEvent = [](const BaseEventInfo* info) {};
    TimePickerModelNG::SetOnChange(frameNode, changeEvent);
    EXPECT_NE(eventHub->changeEvent_, nullptr);
}

/**
 * @tc.name: TimePickerModelNGTest015
 * @tc.desc: Test TimePickerModelNG SetOnEnterSelectedArea.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest015, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme, true);
    auto timePickerModelNG = TimePickerModelNG::GetInstance();
    CHECK_NULL_VOID(timePickerModelNG);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    CHECK_NULL_VOID(frameNode);
    auto eventHub = frameNode->GetEventHub<TimePickerEventHub>();
    CHECK_NULL_VOID(eventHub);
    auto selectedAreaEvent = [](const BaseEventInfo* info) {};
    timePickerModelNG->SetOnEnterSelectedArea(selectedAreaEvent);
    EXPECT_NE(eventHub->onEnterSelectedAreaEvent_, nullptr);
}

/**
 * @tc.name: TimePickerModelNGTest016
 * @tc.desc: Test TimePickerModelNG SetChangeEvent.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest016, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme, true);
    auto timePickerModelNG = TimePickerModelNG::GetInstance();
    CHECK_NULL_VOID(timePickerModelNG);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    CHECK_NULL_VOID(frameNode);
    auto eventHub = frameNode->GetEventHub<TimePickerEventHub>();
    CHECK_NULL_VOID(eventHub);
    auto selectedTimeChangeEvent = [](const BaseEventInfo* info) {};
    timePickerModelNG->SetChangeEvent(selectedTimeChangeEvent);
    EXPECT_NE(eventHub->selectedTimeChangeEvent_, nullptr);
}

/**
 * @tc.name: TimePickerModelNGTest017
 * @tc.desc: Test TimePickerModelNG SetEnableCascade.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest017, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    CHECK_NULL_VOID(frameNode);
    auto timePickerRowPattern = frameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    bool isEnableCascade = false;
    TimePickerModelNG::SetEnableCascade(frameNode, isEnableCascade);
    bool ret = timePickerRowPattern->GetEnableCascade();
    EXPECT_EQ(ret, false);

    isEnableCascade = true;
    TimePickerModelNG::SetEnableCascade(frameNode, isEnableCascade);
    ret = timePickerRowPattern->GetEnableCascade();
    EXPECT_EQ(ret, true);
}

/**
 * @tc.name: TimePickerModelNGTest018
 * @tc.desc: Test TimePickerModelNG ConvertFontScaleValue.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerModelNGTest018, TestSize.Level1)
{
    auto pipeline = MockPipelineContext::GetCurrentContext();
    ASSERT_NE(pipeline, nullptr);
    pipeline->SetFontScale(2);
    pipeline->SetFollowSystem(true);
    TimePickerModelNG timepickerModel;
    auto ret = timepickerModel.ConvertFontScaleValue(FONT_VALUE_NOMARL);
    EXPECT_EQ(ret, Dimension(5));
}

/**
 * @tc.name: TimePickerColumnPattern001
 * @tc.desc: Test UpdateColumnChildPosition.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerColumnPattern001, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);

    /**
     * @tc.step: step1. create TimePicker's column pattern.
     */
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    frameNode->MarkModifyDone();
    auto timePickerRowPattern = frameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    auto allChildNode = timePickerRowPattern->GetAllChildNode();
    auto amPmColumn = allChildNode["amPm"].Upgrade();
    ASSERT_NE(amPmColumn, nullptr);
    auto amPmColumnPattern = amPmColumn->GetPattern<TimePickerColumnPattern>();
    ASSERT_NE(amPmColumnPattern, nullptr);
    amPmColumnPattern->SetCurrentIndex(0);
    EXPECT_TRUE(amPmColumnPattern->NotLoopOptions());

    auto host = amPmColumnPattern->GetHost();
    ASSERT_NE(host, nullptr);
    auto options = amPmColumnPattern->GetOptions();
    auto totalOptionCount = options[host];
    EXPECT_EQ(totalOptionCount, HALF_VALUE);

    /**
     * @tc.step: step2. call UpdateColumnChildPosition, selected index is 0, not allow to slide down.
     * @tc.expected: yLast_ is CURRNET_YOFFSET2, offsetCurSet_ is DEFAULT_YOFFSET1, GetCurrentIndex is 0.
     */
    amPmColumnPattern->yOffset_ = 0.f;
    amPmColumnPattern->offsetCurSet_ = DEFAULT_YOFFSET1;
    amPmColumnPattern->yLast_ = DEFAULT_YOFFSET1;
    amPmColumnPattern->UpdateColumnChildPosition(CURRENT_YOFFSET2);

    EXPECT_EQ(amPmColumnPattern->yLast_, CURRENT_YOFFSET2);
    EXPECT_EQ(amPmColumnPattern->offsetCurSet_, DEFAULT_YOFFSET1);
    EXPECT_EQ(amPmColumnPattern->GetCurrentIndex(), 0);
}

/**
 * @tc.name: TimePickerColumnPattern002
 * @tc.desc: Test UpdateColumnChildPosition.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerColumnPattern002, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);

    /**
     * @tc.step: step1. create TimePicker's column pattern.
     */
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    frameNode->MarkModifyDone();
    auto timePickerRowPattern = frameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    auto allChildNode = timePickerRowPattern->GetAllChildNode();
    auto amPmColumn = allChildNode["amPm"].Upgrade();
    ASSERT_NE(amPmColumn, nullptr);
    auto amPmColumnPattern = amPmColumn->GetPattern<TimePickerColumnPattern>();
    ASSERT_NE(amPmColumnPattern, nullptr);
    amPmColumnPattern->SetCurrentIndex(0);
    EXPECT_TRUE(amPmColumnPattern->NotLoopOptions());

    auto host = amPmColumnPattern->GetHost();
    ASSERT_NE(host, nullptr);
    auto options = amPmColumnPattern->GetOptions();
    auto totalOptionCount = options[host];
    EXPECT_EQ(totalOptionCount, HALF_VALUE);

    /**
     * @tc.step: step2. call UpdateColumnChildPosition, selected index is from 0 to 1 after sliding up.
     * @tc.expected: yOffset_ is 0.f, offsetCurSet_ is 0.f, GetCurrentIndex is 1.
     */
    auto midIndex = amPmColumnPattern->GetShowCount() / HALF_VALUE;
    amPmColumnPattern->optionProperties_[midIndex].prevDistance = PREVIOUS_DISTANCE;
    amPmColumnPattern->optionProperties_[midIndex].nextDistance = NEXT_DISTANCE;

    amPmColumnPattern->yLast_ = DEFAULT_YOFFSET1;
    amPmColumnPattern->yOffset_ = CURRENT_YOFFSET1;
    amPmColumnPattern->UpdateColumnChildPosition(CURRENT_YOFFSET1);

    EXPECT_EQ(amPmColumnPattern->yOffset_, 0.f);
    EXPECT_EQ(amPmColumnPattern->offsetCurSet_, 0.f);
    EXPECT_EQ(amPmColumnPattern->GetCurrentIndex(), 1);
}

/**
 * @tc.name: TimePickerColumnPattern003
 * @tc.desc: Test UpdateColumnChildPosition.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerColumnPattern003, TestSize.Level1)
{
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    ASSERT_NE(theme, nullptr);
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);

    /**
     * @tc.step: step1. create TimePicker's column pattern.
     */
    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    frameNode->MarkModifyDone();
    auto timePickerRowPattern = frameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    auto allChildNode = timePickerRowPattern->GetAllChildNode();
    auto amPmColumn = allChildNode["amPm"].Upgrade();
    ASSERT_NE(amPmColumn, nullptr);
    auto amPmColumnPattern = amPmColumn->GetPattern<TimePickerColumnPattern>();
    ASSERT_NE(amPmColumnPattern, nullptr);
    amPmColumnPattern->SetCurrentIndex(0);
    EXPECT_TRUE(amPmColumnPattern->NotLoopOptions());

    auto host = amPmColumnPattern->GetHost();
    ASSERT_NE(host, nullptr);
    auto options = amPmColumnPattern->GetOptions();
    auto totalOptionCount = options[host];
    EXPECT_EQ(totalOptionCount, HALF_VALUE);

    /**
     * @tc.step: step2. call UpdateColumnChildPosition, selected index is 0, not allow to slide down.
     * @tc.expected: yLast_ is CURRNET_YOFFSET2, offsetCurSet_ is DEFAULT_YOFFSET1, GetCurrentIndex is 0.
     */
    amPmColumnPattern->yOffset_ = 0.f;
    amPmColumnPattern->offsetCurSet_ = DEFAULT_YOFFSET2;
    amPmColumnPattern->yLast_ = DEFAULT_YOFFSET2;
    amPmColumnPattern->UpdateColumnChildPosition(CURRENT_YOFFSET2);

    EXPECT_EQ(amPmColumnPattern->yLast_, CURRENT_YOFFSET2);
    EXPECT_EQ(amPmColumnPattern->offsetCurSet_, DEFAULT_YOFFSET2);
    EXPECT_EQ(amPmColumnPattern->GetCurrentIndex(), 0);
}

/**
 * @tc.name: TimePickerUpdateButtonFocus001
 * @tc.desc: Test UpdateButtonDefaultFocus.
 * @tc.type: FUNC
 */
HWTEST_F(TimePickerPatternTestUpdate, TimePickerUpdateButtonFocus001, TestSize.Level1)
{
    /**
     * @tc.step: step1. create TimePicker's button node.
     * @tc.expected: buttonNode is not null.
     */
    std::vector<ButtonInfo> buttonInfos;
    ButtonInfo buttonInfo;
    buttonInfo.text = "OK";
    buttonInfo.isPrimary = true;
    buttonInfo.isAcceptButton = true;
    buttonInfos.push_back(buttonInfo);

    auto buttonNode = FrameNode::GetOrCreateFrameNode(V2::BUTTON_ETS_TAG,
        ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ButtonPattern>(); });
    ASSERT_NE(buttonNode, nullptr);

    /**
     * @tc.step: step2. call UpdateButtonDefaultFocus, set buttonNode as default focus.
     * @tc.expected: focusHub is not default focus.
     */
    auto focusHub = buttonNode->GetOrCreateFocusHub();
    ASSERT_NE(buttonNode, nullptr);
    EXPECT_EQ(focusHub->IsDefaultFocus(), false);

    /**
     * @tc.step: step3. call UpdateButtonDefaultFocus, set buttonNode as default focus.
     * @tc.expected: focusHub is default focus.
     */
    TimePickerDialogView::UpdateButtonDefaultFocus(buttonInfos, buttonNode, true);
    focusHub = buttonNode->GetOrCreateFocusHub();
    ASSERT_NE(buttonNode, nullptr);
    EXPECT_EQ(focusHub->IsDefaultFocus(), true);
}

/**
@tc.name: TestFlushCurrentOptionsNormalCase
@tc.desc: Test FlushCurrentOptions with normal parameters.
@tc.type: FUNC
*/
HWTEST_F(TimePickerPatternTestUpdate, TestFlushCurrentOptionsNormalCase, TestSize.Level1)
{
    bool isDown = true;
    bool isUpateTextContentOnly = false;
    bool isUpdateAnimationProperties = true;
    bool isTossPlaying = false;
    /**
     * @tc.steps: step1. Create TimePicker and get columnPattern.
     */
    auto theme = MockPipelineContext::GetCurrent()->GetTheme<PickerTheme>();
    TimePickerModelNG::GetInstance()->CreateTimePicker(theme);

    auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
    ASSERT_NE(frameNode, nullptr);
    frameNode->MarkModifyDone();
    auto timePickerRowPattern = frameNode->GetPattern<TimePickerRowPattern>();
    ASSERT_NE(timePickerRowPattern, nullptr);
    timePickerRowPattern->UpdateAllChildNode();
    auto allChildNode = timePickerRowPattern->GetAllChildNode();
    auto minuteColumn = allChildNode["hour"].Upgrade();
    ASSERT_NE(minuteColumn, nullptr);

    auto columnPattern = minuteColumn->GetPattern<TimePickerColumnPattern>();
    ASSERT_NE(columnPattern, nullptr);
    columnPattern->SetShowCount(SHOW_COUNT);
    auto showOptionCount = columnPattern->GetShowCount();
    auto child = minuteColumn->GetChildren();
    EXPECT_EQ(showOptionCount, child.size());
    auto initOptionProperties = columnPattern->optionProperties_;
    /*
    @tc.steps: step2. FlushCurrentOptions with parameters1.
    */
    columnPattern->FlushCurrentOptions(isDown, isUpateTextContentOnly, isUpdateAnimationProperties, isTossPlaying);
    auto optionProperties = columnPattern->optionProperties_;
    EXPECT_TRUE(CompareOptionProperties(initOptionProperties, optionProperties));

    /*
    @tc.steps: step3. FlushCurrentOptions with parameters2.
    */
    isDown = false;
    isUpateTextContentOnly = true;
    isUpdateAnimationProperties = false;
    isTossPlaying = true;
    columnPattern->FlushCurrentOptions(isDown, isUpateTextContentOnly, isUpdateAnimationProperties, isTossPlaying);
    optionProperties = columnPattern->optionProperties_;
    EXPECT_TRUE(CompareOptionProperties(initOptionProperties, optionProperties));
}
} // namespace OHOS::Ace::NG
